using System;
using System.Collections.Generic;
using System.Text;

namespace Developex.DatabaseWrapper.Fields
{
	/// <summary>
	/// String field
	/// </summary>
	public class StringField : Field<string>
	{
		#region Fields

		private int maxCharacters = 0;

		#endregion

		#region Public Properties

		/// <summary>
		/// Max characters allowed
		/// </summary>
		public int MaxCharacters
		{
			get { return maxCharacters; }
		}

		#endregion

		#region Constructors

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="name"></param>
		public StringField(string name)
			: base(name)
		{
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="name"></param>
		/// <param name="flags"></param>
		public StringField(string name, FieldFlags flags)
			: base(name, flags)
		{
		}

		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="name"></param>
		/// <param name="flags"></param>
		/// <param name="insertDefaultValue"></param>
		public StringField(string name, FieldFlags flags, string insertDefaultValue)
			: base(name, flags, insertDefaultValue)
		{
		}

		/// <summary>
		/// Custom Constructor
		/// </summary>
		/// <param name="name"></param>
		/// <param name="maxCharacters"></param>
		public StringField(string name, int maxCharacters)
			: base(name)
		{
			this.maxCharacters = maxCharacters;
		}

		/// <summary>
		/// Custom Constructor
		/// </summary>
		/// <param name="name"></param>
		/// <param name="flags"></param>
		/// <param name="maxCharacters"></param>
		public StringField(string name, FieldFlags flags, int maxCharacters)
			: base(name, flags)
		{
			this.maxCharacters = maxCharacters;
		}

		/// <summary>
		/// Custom Constructor
		/// </summary>
		/// <param name="name"></param>
		/// <param name="flags"></param>
		/// <param name="insertDefaultValue"></param>
		/// <param name="maxCharacters"></param>
		public StringField(string name, FieldFlags flags, string insertDefaultValue, int maxCharacters)
			: base(name, flags, insertDefaultValue)
		{
			this.maxCharacters = maxCharacters;
		}

		#endregion

		#region Overrides

		/// <summary>
		/// get/set value
		/// </summary>
		public override string Value
		{
			get { return base.Value; }
			set
			{
				if (maxCharacters > 0 && value != null && value.Length > maxCharacters)
				{
					throw new DatabaseException("Try to set string with more than allowed characters.Field name = " + Name, null,
														 "StringField.Value-get", GetType());
				}
				base.Value = value;
			}
		}

		/// <summary>
		/// Set value, check for DBNull
		/// </summary>
		/// <param name="value"></param>
		protected override void Set(object value)
		{
			if (maxCharacters > 0 && value != DBNull.Value && value != null)
			{
				string str = (string)value;
				if (str.Length > maxCharacters)
				{
					throw new DatabaseException("Try to set string with more than allowed characters.Field name = " + Name, null,
														 "StringField.Set", GetType());
				}
			}
			base.Set(value);
		}

		///<summary>
		/// Create object 
		///</summary>
		///<returns></returns>
		/// <remarks>
		/// Here should be only object creation, all data copy should be in overrided Clone function.
		/// Used only in base version of Clone function.
		/// Should be overrided for ICloneable interface.
		/// </remarks>
		protected override Field<string> CreateObjectForClone()
		{
			return new StringField(null);
		}

		/// <summary>
		/// Clone
		/// </summary>
		/// <returns></returns>
		public override object Clone()
		{
			StringField field = (StringField)base.Clone();
			field.maxCharacters = maxCharacters;
			return field;
		}

		#endregion
	}
}
